package com.guchenbo.example.security;

import org.junit.jupiter.api.Test;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;
import java.util.Set;

/**
 * @Author gucb
 * @Date 2017/9/7.
 */
public class SignatureTest {

    @Test
    public void t1() {
        Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            System.out.println("Provider : " + provider.getName());

            Set<Provider.Service> services = provider.getServices();
            for (Provider.Service service : services) {
                if (service.getType().equals("Signature")) {
                    System.out.println("\t" + service.getAlgorithm());
                }
            }
        }
    }

    @Test
    public void t2(){
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(2048);

            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            Signature signature = Signature.getInstance("SHA1WithRSA");

            String data = "this is data";
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] signData = signature.sign();
            System.out.println(signData.length);

            signature.initVerify(publicKey);
            signature.update(data.getBytes());

            if (signature.verify(signData)) {
                System.out.println(true);
            } else {
                System.out.println(false);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void t3(){
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(2048);

            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            String s = "this is test!!!!";
            String e = enc(publicKey, s);
            String d = den(privateKey, e);

            System.out.println(d.equals(s));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String den(PrivateKey privateKey, String e) {
        Cipher cipher = null;
        try {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] bs = e.getBytes();
            byte[] bs2 = cipher.doFinal(bs);
            return new String(bs2);
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return null;
    }

    private String enc(PublicKey publicKey, String s) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

            byte[] bs = s.getBytes();
            byte[] bs2 = cipher.doFinal(bs);
            return new String(bs2);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }

        return null;
    }

}
